package com.example.test_witns.ui.blog_content;

import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.test_witns.R;
import com.example.test_witns.adapter.images.ImagesAdapter;
import com.example.test_witns.databinding.ActivityBlogContentBinding;
import com.example.test_witns.pojo.Comment;
import com.example.test_witns.pojo.CommentLikedIdsResponse;
import com.example.test_witns.pojo.CommentLikesNumResponse;
import com.example.test_witns.pojo.CommentResponse;
import com.example.test_witns.pojo.CommentUploadResponse;
import com.example.test_witns.pojo.Favorite;
import com.example.test_witns.pojo.FavoriteNumResponse;
import com.example.test_witns.pojo.FavoriteResponse;
import com.example.test_witns.pojo.Like;
import com.example.test_witns.pojo.LikeResponse;
import com.example.test_witns.pojo.LikesNumResponse;
import com.example.test_witns.utils.MyGrammarLocator;
import com.example.test_witns.utils.MyInfosHelper;
import com.google.android.material.bottomsheet.BottomSheetDialog;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import de.hdodenhof.circleimageview.CircleImageView;
import io.noties.markwon.Markwon;
import io.noties.markwon.syntax.Prism4jTheme;
import io.noties.markwon.syntax.Prism4jThemeDefault;
import io.noties.markwon.syntax.SyntaxHighlightPlugin;
import io.noties.prism4j.Prism4j;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;
import retrofit2.http.Query;

/*
    在本类中, 请将favorite和star理解为同一个意思
*/
public class BlogContentActivity extends AppCompatActivity implements ImagesAdapter.OnHeightChangeListener{
    private static final Logger log = LoggerFactory.getLogger(BlogContentActivity.class);
    private ActivityBlogContentBinding binding;
    private String authorAvatarURL;
    private String authorNameString;
    private String mainTitleString;
    private String subTitleString;
    private String publishTimeString;
    private String contentString;
    private Long blogID;
    private int likes_num;
    private int stars_num;
    private int comments_num;
    private boolean isLiked = false;
    private boolean isStared = false;
    private LinearLayout llComments;
    private boolean orderMethod;
    private List<Long> commentIds = new ArrayList<>();
    private Set<Long> likedCommentIdsSet = new HashSet<>();
    private RecyclerView image_recycler;
    private LinearLayout llImage;
    private String blogContentImageURLs;
    MyInfosHelper myInfosHelper = new MyInfosHelper(BlogContentActivity.this);

    @Override
    public void onHeightChange(int height) {
        ViewGroup.LayoutParams layoutParams = image_recycler.getLayoutParams();
        layoutParams.height = height;
        image_recycler.setLayoutParams(layoutParams);
    }

    public interface CommentApiService{
        @GET("getCommentByBlogID")
        Call<CommentResponse> getCommentByBlogID(@Query("blog_ID") long blog_ID);

        @POST("uploadComment")
        Call<CommentUploadResponse> uploadComment(@Body Comment comment);

        @PUT("/{blogId}/updateCommentsNum")
        Call<CommentResponse> updateCommentsNum(
                @Path("blogId") long blogId,
                @Query("commentsNum") int commentsNum
        );

        @GET("likedComments")
        Call<CommentLikedIdsResponse> getLikedCommentsByCommentIds(
                @Query("userEmail") String userEmail,
                @Query("blogId") Long blogId
        );
    }

    public interface CommentLikesApiService{
        @POST("/{commentId}/like")
        Call<CommentResponse> likeComment(
                @Path("commentId") long commentId,
                @Query("userEmail") String userEmail,
                @Query("blogId") long blogId
        );

        @POST("/{commentId}/unlike")
        Call<CommentResponse> unlikeComment(
                @Path("commentId") long commentId,
                @Query("userEmail") String userEmail
        );

        @GET("/{commentId}/likesCount")
        Call<CommentLikesNumResponse> getLikesCount(
                @Path("commentId") long commentId
        );

        @POST("updateCommentLikesNum")
        Call<CommentResponse> updateCommentLikesNum(
                @Query("commentId") long commentId,
                @Query("newLikesNum") int newLikesNum
        );

        @FormUrlEncoded
        @POST("/api/updateReplyNum")
        Call<CommentResponse> updateReplyNum(
                @Field("commentId") long commentId,
                @Field("newReplyNum") int newReplyNum
        );
    }

    public interface LikeApiService{
        @GET("hasLikedBlog")
        Call<LikeResponse> hasLikedBlog(@Query("userEmail") String userEmail, @Query("blogId") long blogId);

        @GET("getLikesNumByBlogId")
        Call<LikesNumResponse> getLikesNumByBlogId(@Query("blogId") long blogId);

        @POST("likeBlog")
        Call<LikeResponse> likeBlog(@Body Like like);

        @DELETE("/unlikeBlog/{blogId}")
        Call<LikeResponse> unlikeBlog(
                @Path("blogId") long blogId,
                @Query("userEmail") String userEmail
        );

        @PUT("/{blogId}/updateLikesNum")
        Call<LikeResponse> updateLikesNum(
                @Path("blogId") long blogId,
                @Query("likesNum") int likesNum
        );
    }

    public interface FavoriteApiService{
        @GET("hasFavoritedBlog")
        Call<FavoriteResponse> hasFavoritedBlog(@Query("userEmail") String userEmail, @Query("blogId") long blogId);

        @GET("getFavoriteNumByBlogId")
        Call<FavoriteNumResponse> getFavoriteNumByBlogId(@Query("blogId") long blogId);

        @POST("favoriteBlog")
        Call<FavoriteResponse> favoriteBlog(@Body Favorite favorite);

        @DELETE("/unfavoriteBlog/{blogId}")
        Call<FavoriteResponse> unfavoriteBlog(
                @Path("blogId") long blogId,
                @Query("userEmail") String userEmail
        );

        @PUT("/{blogId}/updateStarsNum")
        Call<FavoriteResponse> updateStarsNum(
                @Path("blogId") long blogId,
                @Query("starsNum") int starsNum
        );
    }

    public interface LikeCallback{
        void onSuccess(boolean isLiked);
        void onFailure(String errorMessage);
    }

    public interface UnLikeCallback{
        void onSuccess(boolean isUnliked);
        void onFailure(String errorMessage);
    }

    public interface FavoriteCallback{
        void OnSuccess(boolean isStared);
        void onFailure(String errorMessage);
    }

    public interface unFavoriteCallback{
        void OnSuccess(boolean isUnfavorited);
        void onFailure(String errorMessage);
    }

    public interface GetLikesNumCallback{
        void OnSuccess(int likesNum);
        void onFailure(String errorMessage);
    }

    public interface GetStarsNumCallback{
        void OnSuccess(int starsNum);
        void onFailure(String errorMessage);
    }

    public interface GetLikedCommentsCallback{
        void OnSuccess(List<Long> likedCommentIds);
        void onFailure(String errorMessage);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityBlogContentBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        llComments = findViewById(R.id.llcomment);

        Intent intent = getIntent();
        mainTitleString = intent.getStringExtra("mainTitle");
        subTitleString = intent.getStringExtra("subTitle");
        authorAvatarURL = intent.getStringExtra("authorAvatarURL");
        publishTimeString = intent.getStringExtra("publishTime");
        authorNameString = intent.getStringExtra("authorName");
        contentString = intent.getStringExtra("content");
        likes_num = intent.getIntExtra("likes_num", 0);
        stars_num = intent.getIntExtra("stars_num", 0);
        comments_num = intent.getIntExtra("comments_num", 0);
        blogID = intent.getLongExtra("blogID", 0);
        blogContentImageURLs = intent.getStringExtra("blogContentImageURLs");

        if(blogContentImageURLs != null){
            llImage = findViewById(R.id.llImage);
            String[] blogContentImageURLsString = blogContentImageURLs.split(",");
            for (String blogContentImageURL : blogContentImageURLsString){
                addImageView("https://fftechuseravater.oss-cn-beijing.aliyuncs.com/images/blogContentImages/" + blogContentImageURL);
            }
        }

        TextView order_comment_by_time = findViewById(R.id.order_comment_by_time);
        TextView order_comment_by_recommendation = findViewById(R.id.order_comment_by_recommendation);

        order_comment_by_time.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                order_comment_by_time.setTextColor(Color.parseColor("#000000"));
                order_comment_by_recommendation.setTextColor(Color.parseColor("#aaaaaa"));
            }
        });

        order_comment_by_recommendation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                order_comment_by_time.setTextColor(Color.parseColor("#aaaaaa"));
                order_comment_by_recommendation.setTextColor(Color.parseColor("#000000"));
            }
        });

        Objects.requireNonNull(getSupportActionBar()).hide();
        Window window = getWindow();
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

        window.setStatusBarColor(Color.parseColor("#eeeeee"));

        View blog_content_back = findViewById(R.id.blog_content_back);
        blog_content_back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        GridLayout blog_content_func_area = findViewById(R.id.blog_content_func_area);
        TextView post_comment = findViewById(R.id.post_comment);
        EditText post_comment_edittext = findViewById(R.id.post_comment_edittext);
        post_comment_edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus){
                    blog_content_func_area.setVisibility(View.INVISIBLE);
                    post_comment.setVisibility(View.VISIBLE);
                }else {
                    blog_content_func_area.setVisibility(View.VISIBLE);
                    post_comment.setVisibility(View.INVISIBLE);
                }
            }
        });
        post_comment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Comment comment = new Comment(0,myInfosHelper.getMyNickname(),post_comment_edittext.getText().toString(),
                        blogID, myInfosHelper.getMyAvatarURL(), "2025-01-15 10:30:00",0, 0, null);
                uploadComment(comment);
                addCommentView(comment, false);
                comments_num++;
                TextView comments_num_main = findViewById(R.id.comments_num_main);
                comments_num_main.setText(String.valueOf(comments_num));
                TextView blog_comments_num = findViewById(R.id.blog_comments_num);
                blog_comments_num.setText(String.valueOf(comments_num));
                updateCommentsNum(comments_num);
                if (post_comment_edittext.hasFocus()){
                    post_comment_edittext.clearFocus();
                }
                post_comment_edittext.setText("");
            }
        });
        View blog_content = findViewById(R.id.blog_content);
        blog_content.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (post_comment_edittext.hasFocus()){
                    post_comment_edittext.clearFocus();
                }
                return true;
            }
        });

        ImageView blog_likes = findViewById(R.id.blog_likes);
        TextView blog_likes_num = findViewById(R.id.blog_likes_num);
        View blog_like_content_end = findViewById(R.id.blog_like_content_end);
        ImageView blog_like_content_end_image_view = findViewById(R.id.blog_like_content_end_image_view);
        blog_likes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isLiked){
                    unlikeBlog(myInfosHelper.getMyUserId(), blogID, new LikeCallback() {
                        @Override
                        public void onSuccess(boolean isLiked) {
                            if (!isLiked){
                                blog_likes.setImageResource(R.drawable.unchecked_like_foreground);
                                blog_like_content_end_image_view.setImageResource(R.drawable.unchecked_like_foreground);
                                int likes_num = Integer.parseInt(blog_likes_num.getText().toString());
                                blog_likes_num.setText(String.valueOf(likes_num - 1));
                                updateLikesNum(likes_num - 1);
                            }
                        }
                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }else {
                    likeBlog(myInfosHelper.getMyUserId(), blogID, new LikeCallback() {
                        @Override
                        public void onSuccess(boolean isLiked) {
                            if (isLiked) {
                                blog_likes.setImageResource(R.drawable.like_done_foreground);
                                blog_like_content_end_image_view.setImageResource(R.drawable.like_done_foreground);
                                int likes_num = Integer.parseInt(blog_likes_num.getText().toString());
                                blog_likes_num.setText(String.valueOf(likes_num + 1));
                                updateLikesNum(likes_num + 1);
                            }
                        }

                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }
            }
        });
        blog_like_content_end.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isLiked){
                    unlikeBlog(myInfosHelper.getMyUserId(), blogID, new LikeCallback() {
                        @Override
                        public void onSuccess(boolean isLiked) {
                            if (!isLiked){
                                blog_likes.setImageResource(R.drawable.unchecked_like_foreground);
                                blog_like_content_end_image_view.setImageResource(R.drawable.unchecked_like_foreground);
                                int likes_num = Integer.parseInt(blog_likes_num.getText().toString());
                                blog_likes_num.setText(String.valueOf(likes_num - 1));
                                updateLikesNum(likes_num - 1);
                            }
                        }
                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }else {
                    likeBlog(myInfosHelper.getMyUserId(), blogID, new LikeCallback() {
                        @Override
                        public void onSuccess(boolean isLiked) {
                            if (isLiked) {
                                blog_likes.setImageResource(R.drawable.like_done_foreground);
                                blog_like_content_end_image_view.setImageResource(R.drawable.like_done_foreground);
                                int likes_num = Integer.parseInt(blog_likes_num.getText().toString());
                                blog_likes_num.setText(String.valueOf(likes_num + 1));
                                updateLikesNum(likes_num + 1);
                            }
                        }

                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }
            }
        });

        ImageView blog_stars = findViewById(R.id.blog_stars);
        TextView blog_stars_num = findViewById(R.id.blog_stars_num);
        View blog_star_content_end = findViewById(R.id.blog_star_content_end);
        ImageView blog_star_content_end_image_view = findViewById(R.id.blog_star_content_end_image_view);
        blog_stars.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isStared){
                    unfavoriteBlog(myInfosHelper.getMyUserId(), blogID, new FavoriteCallback() {
                        @Override
                        public void OnSuccess(boolean isFavorited) {
                            if (!isFavorited) {
                                blog_stars.setImageResource(R.drawable.unchecked_star_foreground);
                                blog_star_content_end_image_view.setImageResource(R.drawable.unchecked_star_foreground);
                                int stars_num = Integer.parseInt(blog_stars_num.getText().toString());
                                blog_stars_num.setText(String.valueOf(stars_num - 1));
                                updateStarsNum(stars_num - 1);
                            }
                        }

                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }else {
                    favoriteBlog(myInfosHelper.getMyUserId(), blogID, new FavoriteCallback() {
                        @Override
                        public void OnSuccess(boolean isFavorited) {
                            if (isFavorited) {
                                blog_stars.setImageResource(R.drawable.star_done_foreground);
                                blog_star_content_end_image_view.setImageResource(R.drawable.star_done_foreground);
                                int stars_num = Integer.parseInt(blog_stars_num.getText().toString());
                                blog_stars_num.setText(String.valueOf(stars_num + 1));
                                updateStarsNum(stars_num + 1);
                            }
                        }

                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }

            }
        });
        blog_star_content_end.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isStared){
                    unfavoriteBlog(myInfosHelper.getMyUserId(), blogID, new FavoriteCallback() {
                        @Override
                        public void OnSuccess(boolean isFavorited) {
                            if (!isFavorited) {
                                blog_stars.setImageResource(R.drawable.unchecked_star_foreground);
                                blog_star_content_end_image_view.setImageResource(R.drawable.unchecked_star_foreground);
                                int stars_num = Integer.parseInt(blog_stars_num.getText().toString());
                                blog_stars_num.setText(String.valueOf(stars_num - 1));
                                /*还得先查*/
                                updateStarsNum(stars_num - 1);
                            }
                        }

                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }else {
                    favoriteBlog(myInfosHelper.getMyUserId(), blogID, new FavoriteCallback() {
                        @Override
                        public void OnSuccess(boolean isFavorited) {
                            if (isFavorited) {
                                blog_stars.setImageResource(R.drawable.star_done_foreground);
                                blog_star_content_end_image_view.setImageResource(R.drawable.star_done_foreground);
                                int stars_num = Integer.parseInt(blog_stars_num.getText().toString());
                                blog_stars_num.setText(String.valueOf(stars_num + 1));
                                updateStarsNum(stars_num + 1);
                            }
                        }

                        @Override
                        public void onFailure(String errorMessage) {

                        }
                    });
                }
            }
        });
        View blog_share_content_end = findViewById(R.id.blog_share_content_end);
        blog_share_content_end.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.setType("text/plain");
                intent.putExtra(Intent.EXTRA_TEXT, "这是要分享的文本内容");
                startActivity(Intent.createChooser(intent, "分享到"));
            }
        });

        CircleImageView authorAvatar = findViewById(R.id.authorAvatar);
        TextView authorName = findViewById(R.id.authorName);
        TextView mainTitle = findViewById(R.id.mainTitle);
        TextView subTitle = findViewById(R.id.subTitle);
        TextView publishTime = findViewById(R.id.publishTime);

        Glide.with(authorAvatar.getContext())
                .load(authorAvatarURL)
                .into(authorAvatar);

        authorName.setText(authorNameString);
        mainTitle.setText(mainTitleString);
        subTitle.setText(subTitleString);
        publishTime.setText(publishTimeString);

        TextView test_code = findViewById(R.id.test_code);
        String markdown = contentString;

        // 创建Markwon实例，并添加SyntaxHighlightPlugin插件
        final Prism4j prism4j = new Prism4j(new MyGrammarLocator());
        Prism4jTheme theme = Prism4jThemeDefault.create();
        final Markwon markwon = Markwon.builder(this)
                .usePlugin(SyntaxHighlightPlugin.create(prism4j, theme))
                .build();
        markwon.setMarkdown(test_code, markdown);

        LoadComments(blogID);

        getLikes_num(blogID, new GetLikesNumCallback() {
            @Override
            public void OnSuccess(int likesNum) {
                blog_likes_num.setText(String.valueOf(likes_num));
            }

            @Override
            public void onFailure(String errorMessage) {

            }
        });
        getStars_num(blogID, new GetStarsNumCallback() {
            @Override
            public void OnSuccess(int starsNum) {
                blog_stars_num.setText(String.valueOf(stars_num));
            }

            @Override
            public void onFailure(String errorMessage) {

            }
        });

        checkIfLiked(myInfosHelper.getMyUserId(), blogID, new LikeCallback() {
            @Override
            public void onSuccess(boolean isLiked) {
                if (isLiked){
                    blog_likes.setImageResource(R.drawable.like_done_foreground);
                    blog_like_content_end_image_view.setImageResource(R.drawable.like_done_foreground);
                }
            }

            @Override
            public void onFailure(String errorMessage) {
                Toast.makeText(BlogContentActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
            }
        });

        checkIfFavorited(myInfosHelper.getMyUserId(), blogID, new FavoriteCallback() {
            @Override
            public void OnSuccess(boolean isStared) {
                if (isStared){
                    blog_stars.setImageResource(R.drawable.star_done_foreground);
                    blog_star_content_end_image_view.setImageResource(R.drawable.star_done_foreground);
                }
            }

            @Override
            public void onFailure(String errorMessage) {
                Toast.makeText(BlogContentActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void updateLikesNum(int likes_numAfterUpdate){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.LikeApiService likeApiService = retrofit.create(BlogContentActivity.LikeApiService.class);
        Call<LikeResponse> call = likeApiService.updateLikesNum(blogID, likes_numAfterUpdate);
        call.enqueue(new Callback<LikeResponse>() {
            @Override
            public void onResponse(Call<LikeResponse> call, Response<LikeResponse> response) {
                if (!(response.body() != null && response.body().getStatus() == 1)) {
                    Toast.makeText(BlogContentActivity.this, "点赞数量更新失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<LikeResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void updateStarsNum(int stars_numAfterUpdate){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.FavoriteApiService favoriteApiService = retrofit.create(BlogContentActivity.FavoriteApiService.class);
        Call<FavoriteResponse> call = favoriteApiService.updateStarsNum(blogID, stars_numAfterUpdate);
        call.enqueue(new Callback<FavoriteResponse>() {
            @Override
            public void onResponse(Call<FavoriteResponse> call, Response<FavoriteResponse> response) {
                if (!(response.body() != null && response.body().getStatus() == 1)) {
                    Toast.makeText(BlogContentActivity.this, "收藏数量更新失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<FavoriteResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });

    }

    public void getLikes_num(long blogID, final GetLikesNumCallback getLikesNumCallback){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.LikeApiService likeApiService = retrofit.create(BlogContentActivity.LikeApiService.class);
        Call<LikesNumResponse> call = likeApiService.getLikesNumByBlogId(blogID);
        call.enqueue(new Callback<LikesNumResponse>() {
            @Override
            public void onResponse(Call<LikesNumResponse> call, Response<LikesNumResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1) {
                    likes_num = response.body().getData();
                    getLikesNumCallback.OnSuccess(likes_num);
                }
            }

            @Override
            public void onFailure(Call<LikesNumResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void getStars_num(long blogID, GetStarsNumCallback getStarsNumCallback){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.FavoriteApiService favoriteApiService = retrofit.create(BlogContentActivity.FavoriteApiService.class);
        Call<FavoriteNumResponse> call = favoriteApiService.getFavoriteNumByBlogId(blogID);
        call.enqueue(new Callback<FavoriteNumResponse>() {
            @Override
            public void onResponse(Call<FavoriteNumResponse> call, Response<FavoriteNumResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1) {
                    stars_num = response.body().getData();
                    getStarsNumCallback.OnSuccess(stars_num);
                }else {
                    Toast.makeText(BlogContentActivity.this, "收藏数量获取失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<FavoriteNumResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void uploadComment(Comment comment){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.CommentApiService commentApiService = retrofit.create(BlogContentActivity.CommentApiService.class);
        Call<CommentUploadResponse> call = commentApiService.uploadComment(comment);
        call.enqueue(new Callback<CommentUploadResponse>() {
            @Override
            public void onResponse(Call<CommentUploadResponse> call, Response<CommentUploadResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1) {
                    Toast.makeText(BlogContentActivity.this, "发表成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(BlogContentActivity.this, "发表失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<CommentUploadResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void LoadComments(long targetBlogID){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.CommentApiService commentApiService = retrofit.create(BlogContentActivity.CommentApiService.class);
        Call<CommentResponse> call = commentApiService.getCommentByBlogID(targetBlogID);
        call.enqueue(new Callback<CommentResponse>() {

            @Override
            public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
                if (response.isSuccessful() && response.body() != null) {
                    CommentResponse commentResponse = response.body();
                    // 打印返回的数据类
                    Log.d("RetrofitResponse", commentResponse.toString());

                    if (commentResponse.getData() != null){
                        for (Comment comment : commentResponse.getData()) {
                            commentIds.add(comment.getComment_ID());
                            Log.d("Comment", comment.toString());
                        }
                        getLikedComments(myInfosHelper.getMyUserId(), blogID, new GetLikedCommentsCallback() {
                            @Override
                            public void OnSuccess(List<Long> likedCommentIds) {
                                likedCommentIdsSet.addAll(likedCommentIds);
                                for (Comment comment : commentResponse.getData()) {
                                    addCommentView(comment, likedCommentIdsSet.contains(comment.getComment_ID()));
                                }
                            }

                            @Override
                            public void onFailure(String errorMessage) {

                            }
                        });
                        TextView comments_num_main = findViewById(R.id.comments_num_main);
                        comments_num_main.setText(String.valueOf(comments_num));
                        TextView blog_comments_num = findViewById(R.id.blog_comments_num);
                        blog_comments_num.setText(String.valueOf(comments_num));
                    }
                } else {
                    // 请求成功但返回的数据为空或状态码不是 200
                    Log.e("RetrofitError", "Response is not successful or body is null");
                }
            }

            /**
             * @param call
             * @param t
             */
            @Override
            public void onFailure(Call<CommentResponse> call, Throwable t) {

            }
        });
    }

    public void likeComment(String userEmail, long commentId, long blogID, int currentLikesNum){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.CommentLikesApiService commentApiService = retrofit.create(BlogContentActivity.CommentLikesApiService.class);
        Call<CommentResponse> call = commentApiService.likeComment(commentId, userEmail, blogID);
        call.enqueue(new Callback<CommentResponse>() {
            @Override
            public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1) {
                    updateCommentLikesNum(commentId, currentLikesNum + 1);
                    Toast.makeText(BlogContentActivity.this, "点赞成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(BlogContentActivity.this, "点赞失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<CommentResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "null", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void unlikeComment(String userEmail, long commentId, int currentLikesNum){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.CommentLikesApiService commentApiService = retrofit.create(BlogContentActivity.CommentLikesApiService.class);
        Call<CommentResponse> call = commentApiService.unlikeComment(commentId, userEmail);
        call.enqueue(new Callback<CommentResponse>() {
            @Override
            public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1) {
                    updateCommentLikesNum(commentId, currentLikesNum - 1);
                    Toast.makeText(BlogContentActivity.this, "取消点赞", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(BlogContentActivity.this, "取消点赞失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<CommentResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void updateCommentLikesNum(long commentId, int commentLikesNumAfterUpdate){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.CommentLikesApiService commentApiService = retrofit.create(BlogContentActivity.CommentLikesApiService.class);
        Call<CommentResponse> call = commentApiService.updateCommentLikesNum(commentId, commentLikesNumAfterUpdate);
        call.enqueue(new Callback<CommentResponse>() {
            @Override
            public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
                if (!(response.body() != null && response.body().getStatus() == 1)){
                    Toast.makeText(BlogContentActivity.this, "点赞数量更新失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<CommentResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void updateCommentsNum(int comments_numAfterUpdate){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.CommentApiService commentApiService = retrofit.create(BlogContentActivity.CommentApiService.class);
        Call<CommentResponse> call = commentApiService.updateCommentsNum(blogID, comments_numAfterUpdate);
        call.enqueue(new Callback<CommentResponse>() {
            @Override
            public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
                if (!(response.body() != null && response.body().getStatus() == 1)) {
                    Toast.makeText(BlogContentActivity.this, "评论数量更新失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<CommentResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });

    }

    private void addCommentView(Comment comment, boolean isCurrentUserLiked) {
        AtomicBoolean innerIsCurrentUserLiked = new AtomicBoolean(isCurrentUserLiked);
        View view = getLayoutInflater().inflate(R.layout.item_comment, llComments, false);
        CircleImageView comment_writer_avatar = view.findViewById(R.id.comment_writer_avatar);
        TextView comment_writer_name = view.findViewById(R.id.comment_writer_name);
        TextView comment_publishTime = view.findViewById(R.id.comment_publishTime);
        TextView comment_recommend_value = view.findViewById(R.id.comment_recommend_value);
        TextView comment_content = view.findViewById(R.id.comment_content);
        ImageView comment_recommend = view.findViewById(R.id.comment_recommend);
        ImageView comment_more = view.findViewById(R.id.comment_more);
        Glide.with(view.getContext())
                .load(comment.getWriter_Avatar_URL())
                .into(comment_writer_avatar);

        if (isCurrentUserLiked){
            comment_recommend.setImageResource(R.drawable.recommend_checked_foreground);
            int recommend_num = Integer.parseInt(comment_recommend_value.getText().toString());
        }

        if (comment_recommend != null) {
            comment_more.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showBottomSheetDialog();
                }
            });
            comment_recommend.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (innerIsCurrentUserLiked.get()){
                        comment_recommend.setImageResource(R.drawable.recommend_unchecked_foreground);
                        int recommend_num = Integer.parseInt(comment_recommend_value.getText().toString());
                        comment_recommend_value.setText(String.valueOf(recommend_num - 1));
                        unlikeComment(myInfosHelper.getMyUserId(), comment.getComment_ID(), recommend_num);
                        innerIsCurrentUserLiked.set(false);
                    }else {
                        comment_recommend.setImageResource(R.drawable.recommend_checked_foreground);
                        int recommend_num = Integer.parseInt(comment_recommend_value.getText().toString());
                        comment_recommend_value.setText(String.valueOf(recommend_num + 1));
                        likeComment(myInfosHelper.getMyUserId(), comment.getComment_ID(), comment.getTarget_Blog_ID(), recommend_num);
                        innerIsCurrentUserLiked.set(true);
                    }
                }
            });
        }else {
            Toast.makeText(this, "null", Toast.LENGTH_SHORT).show();
        }

        comment_writer_name.setText(comment.getWriter());
        comment_publishTime.setText(comment.getPublish_Time());
        comment_recommend_value.setText(String.valueOf(comment.getLikes_num()));
        comment_content.setText(comment.getContent());

        llComments.addView(view);
    }

    private void addImageView(String URL) {
        View view = getLayoutInflater().inflate(R.layout.item_image, llImage, false);
        ImageView imageView = view.findViewById(R.id.imageView);
        Glide.with(view.getContext())
                .load(URL)
                .into(imageView);

        llImage.addView(view);
    }

    public void getLikedComments(String userEmail, Long blogID, GetLikedCommentsCallback getLikedCommentsCallback){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.CommentApiService commentApiService = retrofit.create(BlogContentActivity.CommentApiService.class);
        Call<CommentLikedIdsResponse> call = commentApiService.getLikedCommentsByCommentIds(userEmail, blogID);
        call.enqueue(new Callback<CommentLikedIdsResponse>() {
            @Override
            public void onResponse(Call<CommentLikedIdsResponse> call, Response<CommentLikedIdsResponse> response) {
                if (response.body() != null) {
                    getLikedCommentsCallback.OnSuccess(response.body().getData());
                }else {
                    Toast.makeText(BlogContentActivity.this, "获取已点赞评论失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<CommentLikedIdsResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void checkIfLiked(String userEmail, long blogID, final LikeCallback likeCallback){

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.LikeApiService likeApiService = retrofit.create(BlogContentActivity.LikeApiService.class);
        Call<LikeResponse> call = likeApiService.hasLikedBlog(userEmail, blogID);
        call.enqueue(new Callback<LikeResponse>() {
            @Override
            public void onResponse(Call<LikeResponse> call, Response<LikeResponse> response) {
                if (response.body() != null && response.body().getData()) {
                    isLiked = true;
                    likeCallback.onSuccess(isLiked);
                }else {
                    likeCallback.onSuccess(isLiked);
                }
            }

            @Override
            public void onFailure(Call<LikeResponse> call, Throwable t) {
                likeCallback.onFailure("网络错误");
            }
        });
    }

    private void checkIfFavorited(String userEmail, long blogID, final FavoriteCallback favoriteCallback){

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.FavoriteApiService favoriteApiService = retrofit.create(BlogContentActivity.FavoriteApiService.class);
        Call<FavoriteResponse> call = favoriteApiService.hasFavoritedBlog(userEmail, blogID);
        call.enqueue(new Callback<FavoriteResponse>() {
            @Override
            public void onResponse(Call<FavoriteResponse> call, Response<FavoriteResponse> response) {
                if (response.body() != null && response.body().getData()) {
                    isStared = true;
                    favoriteCallback.OnSuccess(isStared);
                }else {
                    favoriteCallback.OnSuccess(isStared);
                }
            }

            @Override
            public void onFailure(Call<FavoriteResponse> call, Throwable t) {
                favoriteCallback.onFailure("网络错误");
            }
        });
    }

    public void favoriteBlog(String userEmail, long blogID, final FavoriteCallback favoriteCallback){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.FavoriteApiService favoriteApiService = retrofit.create(BlogContentActivity.FavoriteApiService.class);
        Favorite favorite = new Favorite(userEmail, blogID);
        Call<FavoriteResponse> call = favoriteApiService.favoriteBlog(favorite);
        call.enqueue(new Callback<FavoriteResponse>() {
            @Override
            public void onResponse(Call<FavoriteResponse> call, Response<FavoriteResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1){
                    isStared = true;
                    favoriteCallback.OnSuccess(isStared);
                    Toast.makeText(BlogContentActivity.this, "收藏成功", Toast.LENGTH_SHORT).show();
                }else {
                    favoriteCallback.OnSuccess(isStared);
                    Toast.makeText(BlogContentActivity.this, "收藏失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<FavoriteResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络状况不佳", Toast.LENGTH_SHORT).show();
                favoriteCallback.onFailure("网络状况不佳");
            }
        });
    }

    public void unfavoriteBlog(String userEmail, long blogID, final FavoriteCallback favoriteCallback){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.FavoriteApiService favoriteApiService = retrofit.create(BlogContentActivity.FavoriteApiService.class);
        Call<FavoriteResponse> call = favoriteApiService.unfavoriteBlog(blogID, userEmail);
        call.enqueue(new Callback<FavoriteResponse>() {
            @Override
            public void onResponse(Call<FavoriteResponse> call, Response<FavoriteResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1){
                    isStared = false;
                    favoriteCallback.OnSuccess(isStared);
                    Toast.makeText(BlogContentActivity.this, "取消收藏", Toast.LENGTH_SHORT).show();
                }else {
                    favoriteCallback.OnSuccess(isStared);
                    Toast.makeText(BlogContentActivity.this, "取消收藏失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<FavoriteResponse> call, Throwable t) {
                favoriteCallback.onFailure("网络状况不佳");
            }
        });
    }

    public void likeBlog(String userEmail, long blogID, final LikeCallback likeCallback){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.LikeApiService likeApiService = retrofit.create(BlogContentActivity.LikeApiService.class);
        Like like = new Like(userEmail, blogID);
        Call<LikeResponse> call = likeApiService.likeBlog(like);
        call.enqueue(new Callback<LikeResponse>() {
            @Override
            public void onResponse(Call<LikeResponse> call, Response<LikeResponse> response) {
                if (response.body().getStatus() == 1){
                    isLiked = true;
                    likeCallback.onSuccess(isLiked);
                    Toast.makeText(BlogContentActivity.this, "点赞成功", Toast.LENGTH_SHORT).show();
                }else {
                    likeCallback.onSuccess(isLiked);
                    Toast.makeText(BlogContentActivity.this, "点赞失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<LikeResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络状况不佳", Toast.LENGTH_SHORT).show();
                likeCallback.onFailure("网络状况不佳");
            }
        });
    }

    public void unlikeBlog(String userEmail, long blogID, final LikeCallback likeCallback){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + "101.35.251.218" + ":8080/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        BlogContentActivity.LikeApiService likeApiService = retrofit.create(BlogContentActivity.LikeApiService.class);
        Call<LikeResponse> call = likeApiService.unlikeBlog(blogID, userEmail);
        call.enqueue(new Callback<LikeResponse>() {
            @Override
            public void onResponse(Call<LikeResponse> call, Response<LikeResponse> response) {
                if (response.body() != null && response.body().getStatus() == 1) {
                    isLiked = false;
                    likeCallback.onSuccess(isLiked);
                    Toast.makeText(BlogContentActivity.this, "取消点赞", Toast.LENGTH_SHORT).show();
                }else {
                    likeCallback.onSuccess(isLiked);
                    Toast.makeText(BlogContentActivity.this, "取消点赞失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<LikeResponse> call, Throwable t) {
                Toast.makeText(BlogContentActivity.this, "网络状况不佳", Toast.LENGTH_SHORT).show();
                likeCallback.onFailure("网络状况不佳");
            }
        });
    }

    private void showBottomSheetDialog() {
        BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
        View view = getLayoutInflater().inflate(R.layout.custom_bottom_sheet_layout, null);

        bottomSheetDialog.setContentView(view);
        bottomSheetDialog.show();

        TextView custom_bottom_sheet_cancel = view.findViewById(R.id.custom_bottom_sheet_cancel);
        custom_bottom_sheet_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bottomSheetDialog.hide();
            }
        });
    }

}
